package t20211227;

/**
 * @Author: DengJia
 * @Date: 2021/12/27 21:13
 * @Description:
 */

public class DynamicFields {
    private Object[][] fields;

    public DynamicFields(int initialSize) {
        fields = new Object[initialSize][2];
        for (int i = 0; i < initialSize; i++) {
            fields[i] = new Object[]{null, null};
        }
    }

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        for (Object[] obj : fields) {
            result.append(obj[0]);
            result.append(" : ");
            result.append(obj[1]);
            result.append("\n");
        }
        return result.toString();
    }

    private int hasField(String id) {
        for (int i = 0; i < fields.length; i++) {
            if (id.equals(fields[i][0])) {
                return i;
            }
        }
        return -1;
    }

    private int getFieldNumber(String id) throws NoSuchFieldException {
        int fieldNum = hasField(id);
        if (fieldNum == -1) {
            throw new NoSuchFieldException();
        }
        return fieldNum;
    }

    private int makeField(String id) {
        for (int i = 0; i < fields.length; i++) {
            if (fields[i][0] == null) {
                fields[i][0] = id;
                return i;
            }
        }
        // 没有空的field，需要新添加一个
        Object[][] tmp = new Object[fields.length + 1][2];
//        for (int i = 0; i < fields.length; i++) {
//            tmp[i] = fields[i];
//        }
        System.arraycopy(fields, 0, tmp, 0, fields.length);
        for (int i = fields.length; i < tmp.length; i++) {
            tmp[i] = new Object[]{null, null};
        }
        fields = tmp;
        // 递归调用来实现增加字段
        return makeField(id);
    }

    public Object getFiled(String id) throws NoSuchFieldException {
        return fields[getFieldNumber(id)][1];
    }

    public Object setField(String id, Object value) throws DynamicFieldsException {
        if (value == null) {
            DynamicFieldsException dfe = new DynamicFieldsException();
            // 通过initCause方法来传入cause
            dfe.initCause(new NullPointerException());
            throw dfe;
        }
        int fieldNum = hasField(id);
        if (fieldNum == -1) {
            fieldNum = makeField(id);
        }
        Object result;
        try {
            result = getFiled(id); // 获取旧值
        } catch (NoSuchFieldException e) {
            // 调用构造器来传入cause
            throw new RuntimeException(e);
        }
        fields[fieldNum][1] = value;
        return result;
    }

    public static void main(String[] args) {
        DynamicFields df = new DynamicFields(3);
        System.out.println(df);
        try {
            df.setField("A", "djosimon.top");
            df.setField("n1", 17);
            df.setField("n2", 99);
            System.out.println(df);
            df.setField("A", "dengjia.top");
            df.setField("n3", 666);
            System.out.println(df);
            System.out.println("df.getFiled(\"A\") = " + df.getFiled("A"));
            Object field = df.setField("d", null); // Exception
        } catch (NoSuchFieldException | DynamicFieldsException e) {
            e.printStackTrace();
        }
    }
}

class DynamicFieldsException extends Exception {
}
